package io.litchi.auth.application.service;

import io.litchi.auth.Infrastructure.common.command.user.SaveUserCommand;
import io.litchi.auth.Infrastructure.common.command.user.UpdateUserCommand;
import io.litchi.auth.Infrastructure.common.query.user.UserListQuery;
import io.litchi.auth.Infrastructure.common.result.user.UserDetailResult;
import io.litchi.auth.Infrastructure.common.result.user.UserListResult;
import io.litchi.auth.domain.entity.auth.User;
import io.litchi.auth.domain.factory.UserFactory;
import io.litchi.auth.domain.repository.UserRepository;
import io.litchi.common.anno.mysql.handler.QueryUtil;
import io.litchi.common.page.PageCondition;
import io.litchi.common.page.PageResult;
import io.litchi.common.result.Result;

import io.micrometer.common.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * 用户
 *
 * @author helang
 * @since 2025-11-11
 */
@Service
@RequiredArgsConstructor
public class UserService {
    private static final String DEFAULT_PASSWORD_PREFIX = "LITCHI";
    private static final String DEFAULT_NICKNAME_PREFIX = "荔枝用户_";

    private final UserRepository userRepository;

    private final UserFactory userFactory;

    private final PasswordEncoder passwordEncoder;


    /**
     * 用户分页查询
     *
     * @param pageCondition 分页条件
     * @return 分页查询结果
     */
    public Result<PageResult<UserListResult>> list(PageCondition<UserListQuery> pageCondition) {

        PageRequest pageRequest = PageRequest.of(pageCondition.getCurrent() - 1, pageCondition.getSize());
        UserListQuery param = pageCondition.getParam();
        Specification<User> userSpecification = QueryUtil.buildQueryJpa(param, User.class);

        Page<User> pageData = userRepository.findAll(userSpecification, pageRequest);
        List<UserListResult> resultlist = new ArrayList<>();
        if (pageData.getTotalElements() > 0) {
            resultlist = pageData.getContent().stream().map(userFactory::mapToUserListResult).toList();
        }

        return Result.success(PageResult.of(resultlist, pageData.getTotalElements()));
    }

    public Result<Boolean> nicknameExist(String nickname) {
        List<User> byNickname = userRepository.findByNickname(nickname);
        return Result.success(!byNickname.isEmpty());
    }

    public Result<Boolean> mobileExist(String mobile) {
        List<User> byMobile = userRepository.findByMobile(mobile);
        return Result.success(!byMobile.isEmpty());
    }

    public Result<UserDetailResult> userDetail(Long id) {
        Optional<User> userDetail = userRepository.findById(id);
        UserDetailResult userDetailResult = userFactory.mapToUserDetail(userDetail.orElse(new User()));
        return Result.success(userDetailResult);
    }

    public Result<Void> saveUser(SaveUserCommand command) {
        User user = userFactory.mapToUserEntity(command);
        // 设置用户名 和 默认密码
        user.setUsername(command.getMobile());
        String mobile4 = command.getMobile().substring(7, 11);
        user.setPassword(passwordEncoder.encode(DEFAULT_PASSWORD_PREFIX + mobile4));
        if (StringUtils.isBlank(command.getNickname())) {
            user.setNickname(DEFAULT_NICKNAME_PREFIX + mobile4);
        }

        userRepository.save(user);
        return Result.success();
    }

    @Transactional
    public Result<Void> updateStatus(   UpdateUserCommand command) {
        userRepository.updateStatusById(command.getId(),command.getStatus());
        return Result.success();
    }
}